<template>
    <div>
        <div v-if="!isRead" class="edu-opertion-bar">
            <div class="float-left"/>
            <div class="float-right">
                <el-button
                    v-if="dataType === '1'"
                    type="primary"
                    @click="addCourseCategory"
                >{{ $t('common.btn.add') }}</el-button>
            </div>
        </div>
        <div v-if="next" class="tip-message">{{ tip }}</div>
        <el-table
            :data="processedData"
            :span-method="arraySpanMethod"
            :summary-method="getSummaries"
            border
        >
            <el-table-column prop="name" label="课程类别" align="center"/>
            <el-table-column label="子类别">
                <template slot-scope="props">{{ props.row.subName }}</template>
            </el-table-column>
            <el-table-column prop="score" label="学分" width="100px">
                <template slot-scope="props">
                    <el-input
                        v-if="!isRead"
                        v-model="props.row.score"
                        type="text"
                        @focus="focusInput(props.row)"
                        @blur="blurInput(props.row)"
                    />
                    <span v-if="isRead">{{ props.row.score }}</span>
                </template>
            </el-table-column>
            <el-table-column prop="percent" label="百分比%" align="center">
                <template
                    v-if="props.row.labelId !== ''"
                    slot-scope="props"
                >{{ getPercent(props.row) }}</template>
            </el-table-column>
            <el-table-column v-if="!isRead" label width="140px">
                <template v-if="props.row.labelId !== ''" slot-scope="props">
                    <el-button type="text" size="mini" @click="removeRow(props.row)">删除</el-button>
                    <el-button
                        v-if=" !!props.row.subName && props.row.subLength !== 1 && props.row.index !== 1"
                        type="text"
                        size="mini"
                        @click="moveUp(props.row)"
                    >上移</el-button>
                    <el-button
                        v-if="!!props.row.subName && props.row.subLength !== 1 && props.row.index != props.row.subLength"
                        type="text"
                        size="mini"
                        @click="moveDown(props.row)"
                    >下移</el-button>
                </template>
            </el-table-column>
            <el-table-column v-if="!isRead" label width="140px">
                <template v-if="props.row.labelId !== ''" slot-scope="props">
                    <el-button
                        v-if="props.row.pindex !== 1"
                        type="text"
                        size="mini"
                        @click="moveUp(props.row, 1)"
                    >上移</el-button>
                    <el-button
                        v-if="topCategoryLength != props.row.pindex"
                        type="text"
                        size="mini"
                        @click="moveDown(props.row, 1)"
                    >下移</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-row v-if="next" class="pd-12px float-right" style="padding-right: 0;">
            <el-col :span="24">
                <el-button size="medium" @click="backStep">上一步</el-button>
                <el-button v-if="!isRead" size="medium" @click="submit(null)">保存</el-button>
                <el-button size="medium" type="primary" @click="nextStep">下一步</el-button>
            </el-col>
        </el-row>

        <el-dialog
            :visible.sync="addCategoryVisible"
            :before-close="handleClose"
            :title="$t('culture.template.addCourseCategory')"
            width="34%"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
        >
            <el-card shadow="never" body-style="padding: 24px;">
                <el-table
                    ref="categoryTable"
                    :span-method="arraySpanMethod"
                    :data="courseCheckedData"
                    border
                    @selection-change="handleSelectionChange"
                >
                    <el-table-column prop="name" label="课程类别" align="center"/>
                    <el-table-column label="子类别">
                        <template slot-scope="props">{{ props.row.subName }}</template>
                    </el-table-column>
                    <el-table-column :label="$t('culture.courseCategory.type')">
                        <template slot-scope="props">
                            <el-select
                                v-model="props.row.labelType"
                                @change="handleLabelTypeChange(props.row)"
                                filterable
                                style="width: 100%"
                            >
                                <el-option
                                    v-for="item in options.labelTypes"
                                    :key="item.value"
                                    :label="item.label"
                                    :value="item.value"
                                ></el-option>
                            </el-select>
                        </template>
                    </el-table-column>
                    <el-table-column type="selection" width="55"/>
                </el-table>
            </el-card>
            <span slot="footer" class="dialog-footer">
                <el-button @click="addCategoryVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitCourseCategory">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>
<script>
import {
    saveCourseCategoryForm,
    getCourseCategoryFormById,
    coursesLabelTreeList,
    batchSaveCultureRule,
    findCheckedCultureLabelList
} from "common/src/api/courseTemplate";
import { deleteCultureRule } from "common/src/api/culture/cultureSchemeRule";
import UTILS from "common/src/utils/utils";
import { queryDic } from "common/src/api/dictionary";
export default {
    name: "CourseCategoryForm",
    props: {
        next: {
            type: Function,
            default: null
        },
        templateId: {
            type: Number,
            default: null
        },
        isRead: {
            type: Boolean,
            default: false
        },
        dataType: {
            type: String,
            default: "1" // 1为模板，2为方案
        }
    },
    data() {
        return {
            tip:
                '"课程类别"会自动关联到相应的学生，请教务员填写每个课程类别的最低学分要求。',
            resCategories: [], // 缓存返回的分类数据
            courseCategories: [], // 原始数据
            processedData: [], // 转换后数据
            courseCheckedData: [], // 课程选择
            courseCheckeds: [],
            topCategoryLength: 0,
            addCategoryVisible: false,
            queryForm: {
                trainingLevel: ""
            },
            options: {
                trainingLevel: [],
                labelTypes: []
            },
            tree: {
                data: [],
                defaultProps: {
                    children: "childs",
                    label: "label"
                },
                checkedList: []
            }
        };
    },
    created() {
        this.getCourseCategory();
        this.initOptions();
    },
    methods: {
        initOptions() {
            const data = {
                lang: this.$store.getters.language || "cn",
                type: "allChild",
                keys: ["X_PYCC", "K_KCLB"]
            };
            queryDic(data).then(res => {
                if (res.code === 200) {
                    UTILS.fillSelect(
                        {
                            trainingLevel: "X_PYCC",
                            labelTypes: "K_KCLB"
                        },
                        res.data,
                        this.options
                    );
                }
            });
        },
        // 输入框获取焦距
        focusInput(row) {
            if (row.score === 0) {
                row.score = "";
            }
        },
        // 输入框失去焦距
        blurInput(row) {
            if (row.score.trim() === "") {
                row.score = 0;
            }
            const value = Number(row.score);
            if (isNaN(value)) {
                row.score = 0;
            } else if (value < 0) {
                row.score = Math.abs(row.score);
            }
            // row.score = Math.floor(row.score); //处理小数
        },
        submit(callback) {
            if (this.processedData.length === 0) {
                this.$message({
                    type: "warning",
                    message: "请添加课程类别！"
                });
                return;
            }
            const data = {
                id: this.templateId,
                cultureRuleList: []
            };
            const totalScore = _.map(this.processedData, "score").reduce(
                function(total, num) {
                    return parseInt(total) + parseInt(num);
                }
            );
            const isTotalMax =
                parseInt(
                    this.processedData[this.processedData.length - 1].score
                ) >=
                totalScore -
                    parseInt(
                        this.processedData[this.processedData.length - 1].score
                    );
            if (!isTotalMax) {
                this.$message({
                    type: "warning",
                    message: "总学分必须大于等于所有课程学分的总和"
                });
                return;
            }
            this.processedData.forEach(row => {
                data.cultureRuleList.push({
                    id: row.id,
                    labelId: row.labelId,
                    credit: row.score,
                    level: row.level,
                    type: this.dataType,
                    orderNo: row.index
                });
            });
            saveCourseCategoryForm(data).then(response => {
                if (response.code === 200) {
                    this.$message({
                        type: "success",
                        message: "保存成功"
                    });
                    if (callback) {
                        callback();
                    }
                }
            });
        },
        // 上一步
        backStep() {
            if (this.next) {
                this.next(-1);
            }
        },
        // 下一步
        nextStep() {
            if (this.isRead) {
                if (this.next) {
                    this.next();
                }
            } else {
                this.submit(() => {
                    if (this.next) {
                        this.next();
                    }
                });
            }
        },
        // 获取百分比
        getPercent(row) {
            const scoresArr = this.processedData.map(p => p.score);
            let totalScore = scoresArr.reduce((prev, curr, index) => {
                const value = Number(curr);
                if (!isNaN(value) && scoresArr.length !== index + 1) {
                    return Number(prev) + Number(curr);
                } else {
                    return Number(prev);
                }
            }, 0);

            if (isNaN(totalScore) || totalScore === 0) {
                totalScore = 1;
            }
            return ((parseFloat(row.score / totalScore).toFixed(4)) * 100).toFixed(2) + '%';
        },
        // 合计
        getSummaries(param) {
            const { columns, data } = param;
            const sums = [];
            columns.forEach((column, index) => {
                if (index === 0) {
                    sums[index] = "总计";
                    return;
                }
                if (index === 1 || index === 3) {
                    sums[index] = "";
                    return;
                }
                const values = data.map(item => Number(item[column.property]));
                sums[index] = values.reduce((prev, curr) => {
                    const value = Number(curr);
                    if (!isNaN(value)) {
                        return prev + curr;
                    } else {
                        return prev;
                    }
                }, 0);
            });
            return sums;
        },
        // 计算合并单元格
        arraySpanMethod({ row, column, rowIndex, columnIndex }) {
            if (columnIndex === 0) {
                if (row.isMixed) {
                    if (row.isFirst) {
                        return {
                            rowspan: row.subLength,
                            colspan: 1
                        };
                    } else {
                        return {
                            rowspan: 0,
                            colspan: 0
                        };
                    }
                }
            }
            if (columnIndex === 5) {
                if (row.isMixed) {
                    if (row.isFirst) {
                        return {
                            rowspan: row.subLength,
                            colspan: 1
                        };
                    } else {
                        return {
                            rowspan: 0,
                            colspan: 0
                        };
                    }
                }
            }
        },
        // 获取课程分类
        getCourseCategory() {
            getCourseCategoryFormById(this.templateId, this.dataType).then(
                response => {
                    if (response.code === 200) {
                        if (
                            response.data.cultureRuleList &&
                            response.data.cultureRuleList.length > 0
                        ) {
                            this.resCategories = response.data.cultureRuleList;
                            this.__fromatData(response.data.cultureRuleList);
                        }
                    }
                }
            );
        },
        // 转换原始数据为视图数据
        __convert() {
            const largeCategories = this.courseCategories.filter(
                c => c.pid === "0"
            );
            const result = [];
            largeCategories.forEach(large => {
                const smallCategories = this.courseCategories.filter(
                    small => small.pid === large.labelId
                );
                // 是否存在子分类
                if (smallCategories.length > 0) {
                    let isFirst = true;
                    smallCategories.forEach(small => {
                        result.push({
                            id: small.id,
                            labelId: small.labelId,
                            name: large.name,
                            score: small.score,
                            subName: small.name,
                            level: small.level,
                            pid: large.labelId,
                            plevel: large.level,
                            isFirst: isFirst,
                            labelType: small.labelType,
                            subLength: smallCategories.length,
                            orderNo: small.orderNo,
                            index: small.index,
                            pindex: large.index,
                            isMixed: true // 包含子分类
                        });
                        isFirst = false;
                    });
                } else {
                    result.push({
                        id: large.id,
                        labelId: large.labelId,
                        level: large.level,
                        name: large.name,
                        score: large.score,
                        orderNo: large.orderNo,
                        index: large.index,
                        pindex: large.index,
                        labelType: large.labelType,
                        subName: ""
                    });
                }
            });
            this.processedData = result;
        },
        // 格式化课程分类数据
        __fromatData(data) {
            this.topCategoryLength = data.filter(o => o.level === "1").length;
            this.courseCategories.length = 0;
            data[0].level = 999;
            data = _.sortBy(data, ["level", "index", "orderNo"]);
            if (data && data.length > 0) {
                data.forEach(row => {
                    if (row.labelId) {
                        this.courseCategories.push({
                            id: row.id,
                            labelId: row.labelId,
                            level: row.level,
                            name: row.label,
                            pid: row.parentId,
                            score: row.credit,
                            orderNo: row.orderNo,
                            labelType: row.labelType,
                            index: row.index
                        });
                    } else {
                        this.courseCategories.push({
                            id: row.id,
                            labelId: "",
                            name: "总学分",
                            pid: "0",
                            score: row.credit,
                            orderNo: row.orderNo,
                            index: row.index
                        });
                    }
                });
            } else if (data) {
                data.coursesLabelList.forEach(row => {
                    this.courseCategories.push({
                        id: row.id,
                        labelId: row.labelId,
                        name: row.label,
                        pid: row.parentId,
                        score: row.credit,
                        orderNo: row.orderNo,
                        labelType: row.labelType,
                        index: row.index
                    });
                });
            }
            this.__convert();
        },
        // 获取所有课程分类
        getAllCourseCategorys() {
            const self = this;
            const that = this;
            const params = {
                templateId: this.templateId
            };
            const data = {
                taringingId: this.templateId,
                type: this.dataType
            };
            const checkedIndexs = [];
            coursesLabelTreeList(params).then(res => {
                if (res && res.code === 200) {
                    this.courseCheckedData = this.__getCategoryList(res.data);
                    findCheckedCultureLabelList(data).then(res => {
                        if (res.data && res.code === 200) {
                            _.forEach(_.map(res.data, "labelId"), item => {
                                checkedIndexs.push(
                                    _.findIndex(self.courseCheckedData, o => {
                                        return o.id === item;
                                    })
                                );
                                let checkedData = _.find(that.processedData, {
                                    labelId: item.toString()
                                });
                                let needCheckedData = _.find(
                                    that.courseCheckedData,
                                    {
                                        id: item
                                    }
                                );
                                if (checkedData && needCheckedData) {
                                    let labelTypeObj = _.find(
                                        that.options.labelTypes,
                                        {
                                            value: checkedData.labelType
                                        }
                                    );

                                    labelTypeObj &&
                                        Vue.set(
                                            needCheckedData,
                                            "labelType",
                                            labelTypeObj.value
                                        );
                                }
                            });
                            _.forEach(checkedIndexs, index => {
                                if (index !== -1) {
                                    this.$refs.categoryTable.toggleRowSelection(
                                        self.courseCheckedData[index]
                                    );
                                }
                            });
                        }
                    });
                }
            });
        },
        __getCategoryList(data) {
            const self = this;
            const returnArr = [];
            _.forEach(data, large => {
                // 是否存在子分类
                if (large.childs) {
                    let isFirst = true;
                    large.childs.forEach(small => {
                        returnArr.push({
                            id: small.id,
                            name: small.parentName,
                            subName: small.label,
                            level: small.level,
                            pid: large.id,
                            plevel: small.level - 1,
                            isFirst: isFirst,
                            labelType: small.labelType,
                            subLength: large.childs.length,
                            isMixed: true // 包含子分类
                        });
                        isFirst = false;
                    });
                } else {
                    returnArr.push({
                        id: large.id,
                        level: large.level,
                        name: large.label,
                        labelType: large.labelType,
                        subName: ""
                    });
                }
                if (large.childs) {
                    returnArr.concat(self.__getCategoryList(large.childs));
                }
            });
            return returnArr;
        },
        addCourseCategory() {
            this.addCategoryVisible = true;
            this.getAllCourseCategorys();
        },
        __getCheckedNodes() {
            //todo
            if (this.courseCheckeds.length == 0) {
                this.$message({ type: "warning", message: "请选择课程类别" });
                return;
            }
            const data = {
                id: this.templateId,
                cultureRuleList: this.courseCheckeds
            };
            batchSaveCultureRule(data).then(res => {
                if (res.code === 200) {
                    this.addCategoryVisible = false;
                    this.getCourseCategory();
                }
            });
        },
        submitCourseCategory() {
            //   this.addCategoryVisible = false;
            this.__getCheckedNodes();
        },
        removeRow(row) {
            const params = {
                id: row.id
            };
            this.$confirm(
                this.$t("common.tips.beSure"),
                this.$t("common.text.info"),
                {
                    confirmButtonText: this.$t("common.btn.confirm"),
                    cancelButtonText: this.$t("common.btn.cancel"),
                    type: "warning"
                }
            ).then(() => {
                let isOnlySubCategory = false;
                if (row.level == 2) {
                    isOnlySubCategory = this.resCategories.filter( e => e.parentId === row.pid).length === 1;
                }
                deleteCultureRule(params).then(res => {
                    if (res.code === 200) {
                        if (isOnlySubCategory) {
                            //删除父类
                            let parentCategory = this.resCategories.find(e => e.labelId === row.pid);
                            if (parentCategory) {
                                deleteCultureRule({id: parentCategory.id}).then(result => {
                                    if (result.code === 200) {
                                        this.getCourseCategory();
                                        this.$message({
                                            type: "success",
                                            message: this.$t("common.tips.deleteSuccess")
                                        });
                                    }
                                })
                            }   

                        } else {
                            this.getCourseCategory();
                            this.$message({
                                type: "success",
                                message: this.$t("common.tips.deleteSuccess")
                            });
                        }
                    }
                });
                
            });
        },
        moveUp(row, flag) {
            let currentItemIndex = -1;
            let targetItemIndex = -1;
            if (flag) {
                const pid = row.pid ? row.pid : row.labelId;
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: pid
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) - 1
                });
            } else {
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: row.labelId
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    parentId: this.resCategories[currentItemIndex].parentId,
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) - 1
                });
            }
            if (currentItemIndex !== -1 && targetItemIndex !== -1) {
                this.resCategories[targetItemIndex].index =
                    parseInt(this.resCategories[targetItemIndex].index) + 1;
                this.resCategories[currentItemIndex].index =
                    parseInt(this.resCategories[currentItemIndex].index) - 1;
                this.__fromatData(this.resCategories);
            }
            this.submit();
        },
        moveDown(row, flag) {
            let currentItemIndex = -1;
            let targetItemIndex = -1;
            if (flag) {
                const pid = row.pid ? row.pid : row.labelId;
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: pid
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) + 1
                });
            } else {
                currentItemIndex = _.findIndex(this.resCategories, {
                    labelId: row.labelId
                });
                targetItemIndex = _.findIndex(this.resCategories, {
                    parentId: this.resCategories[currentItemIndex].parentId,
                    level: this.resCategories[currentItemIndex].level,
                    index:
                        parseInt(this.resCategories[currentItemIndex].index) + 1
                });
            }
            if (currentItemIndex !== -1 && targetItemIndex !== -1) {
                this.resCategories[targetItemIndex].index =
                    parseInt(this.resCategories[targetItemIndex].index) - 1;
                this.resCategories[currentItemIndex].index =
                    parseInt(this.resCategories[currentItemIndex].index) + 1;
                this.__fromatData(this.resCategories);
            }
            this.submit();
        },
        handleSelectionChange(checkeds) {
            const self = this;
            self.courseCheckeds = [];
            if (checkeds.length === 0) return;
            _.forEach(checkeds, item => {
                if (item) {
                    if (item.pid) {
                        self.courseCheckeds.push({
                            labelId: item.pid,
                            level: item.plevel,
                            type: this.dataType
                        });
                    }
                    self.courseCheckeds.push({
                        labelId: item.id,
                        level: item.level,
                        labelType: item.labelType || 0,
                        type: this.dataType
                    });
                }
            });
            self.courseCheckeds = _.unionBy(self.courseCheckeds, "labelId");
        },
        handleLabelTypeChange(item) {
            let changeItem = _.find(this.courseCheckeds, {
                labelId: item.id
            });
            changeItem && (changeItem.labelType = item.labelType);
        }
    }
};
</script>
<style lang="scss" scoped>
.tip-message {
    margin: 10px 0;
    font-size: 14px;
    color: #909090;
}
</style>
